package com.tangcco.lockwell.controller.student;

import cn.hutool.core.util.NumberUtil;
import com.tangcco.lockwell.base.RestResponse;
import com.tangcco.lockwell.context.WebContext;
import com.tangcco.lockwell.domain.*;
import com.tangcco.lockwell.domain.dto.english.AnswerEnglishKeyValueDto;
import com.tangcco.lockwell.domain.dto.english.AnswerEnglishParentDto;
import com.tangcco.lockwell.domain.dto.politics.AnswerPoliticsChildDto;
import com.tangcco.lockwell.domain.dto.politics.AnswerPoliticsParentDto;
import com.tangcco.lockwell.domain.enums.ExamPaperTypeEnum;
import com.tangcco.lockwell.service.*;
import com.tangcco.lockwell.utility.StudentSubjectUtil;
import com.tangcco.lockwell.viewmodel.admin.question.QuestionVm;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 答题相关的控制层
 *
 * @author yanxinping
 * @version 1.0
 * @description: TODO
 * @date 2024/12/19 14:21
 */
@RestController
@RequestMapping("/api/student/answer")
public class AnswerController {
    private static final Logger logger = Logger.getLogger(QuestionController.class);

    @Autowired
    private WebContext webContext;
    @Autowired
    private AnswerSheetService answerSheetService;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private ExamPaperService examPaperService;
    @Autowired
    private WrongQuestionService wrongQuestionService;
    @Autowired
    private StudentSubjectUtil studentSubjectUtil;
    @Autowired
    private AnswerContentRecordService answerContentRecordService;

    /**
     * 政治模块提交答案
     *
     * @param answerPoliticsParentDto
     * @return
     */
    @RequestMapping("/submitAnswerForPolitics")
    @Transactional
    public RestResponse<AnswerSheet> submitAnswer(@RequestBody AnswerPoliticsParentDto answerPoliticsParentDto) {
        List<AnswerPoliticsChildDto> requestAnswerChild = answerPoliticsParentDto.getChildDtos();
        //按答案筛选掉答案为空的数据
        if (CollectionUtils.isEmpty(requestAnswerChild)) {
            logger.info("用户没有选择答案");
            return RestResponse.ok();
        }
        List<AnswerPoliticsChildDto> anwsers = requestAnswerChild.stream().filter(answer ->
                answer.getUserAnswer()!= null).collect(Collectors.toList());
        ExamPaper examPaper = examPaperService.getExamPaperById(answerPoliticsParentDto.getExamPaperId());
        if (examPaper == null) {
            logger.info("考试试卷不存在");
            return RestResponse.ok();
        }
        //当前用户
        Integer userId = webContext.getCurrentUser().getUserId();
        BigDecimal score = BigDecimal.ZERO;
        int correntCount = 0;
        int errorCount = 0;
        int totalCount = examPaper.getQuestionCount() == null ? 0 : examPaper.getQuestionCount();
        for (AnswerPoliticsChildDto answer : anwsers) {
            if (Objects.isNull(answer.getUserAnswer())) {
                continue;
            }
            List<String> arrayList;
            if(answer.getUserAnswer() instanceof List){
                arrayList = (List<String>)answer.getUserAnswer();
            }else{
                arrayList = Arrays.asList(answer.getUserAnswer().toString());
            }
            Question question = questionService.selectBaseInfoById(answer.getQuestionId());
            if (question == null || StringUtils.isBlank(question.getCorrect())) {
                correntCount++;
                for(int i=0;i<arrayList.size();i++){
                    score = score.add(NumberUtil.mul(new BigDecimal(5),BigDecimal.valueOf(0.8)));
                }
                continue;
            }
            HashSet<String> a1;
            a1 = new HashSet<>(arrayList);
            HashSet<String> a2 = new HashSet<>(Arrays.asList(question.getCorrect().split(",")));
            if (a1.equals(a2)) {
                score = score.add(BigDecimal.valueOf(question.getScore()==null?0:question.getScore()));
                correntCount++;
            } else {
                WrongQuestion wr = new WrongQuestion();
                wr.setUserId(userId);
                wr.setQuestionId(answer.getQuestionId());
                List<WrongQuestion> wrongQuestionList = wrongQuestionService.selectList(wr);
                if(CollectionUtils.isEmpty(wrongQuestionList)){
                    WrongQuestion wrNew = new WrongQuestion();
                    wrNew.setUserId(userId);
                    wrNew.setQuestionId(answer.getQuestionId());
                    arrayList.sort(String::compareTo);
                    wrNew.setWrongAnswer(arrayList);
                    wrNew.setNumberErrors(1);
                    wrNew.setResource(answerPoliticsParentDto.getResource());
                    wrongQuestionService.insertSelective(wrNew);
                }else{
                    WrongQuestion wrOld = wrongQuestionList.get(0);
                    wrOld.setNumberErrors(wrOld.getNumberErrors() + 1);
                    arrayList.sort(String::compareTo);
                    wrOld.setWrongAnswer(arrayList);
                    wrongQuestionService.updateByPrimaryKeySelective(wrOld);
                }
                errorCount++;
            }
        }
        if(answerPoliticsParentDto.getIsTest() == null){
            answerPoliticsParentDto.setIsTest(false);
        }
        //更新用户答题记录
        answerContentRecordService.insertOrUpdateForPolitics(answerPoliticsParentDto.getIsTest(),score,anwsers, examPaper, userId, answerPoliticsParentDto.getTotalTimeSpent(),answerPoliticsParentDto.getThisTimeData());
        //如果已存在，则删除重新插入
        AnswerSheet existSheet = new AnswerSheet();
        existSheet.setUserId(userId);
        existSheet.setPaperId(answerPoliticsParentDto.getExamPaperId());
        List<AnswerSheet> answerSheets = answerSheetService.selectList(existSheet);
        Long totalTimeSpent = 0L;
        if (!CollectionUtils.isEmpty(answerSheets)) {
            totalTimeSpent = answerSheets.get(0).getTotalTimeSpent();
            answerSheets.forEach(answerSheet -> {
                answerSheetService.deleteById(answerSheet.getId());
            });
        }
        AnswerSheet answerSheet = new AnswerSheet();
        answerSheet.setUserId(userId);
        answerSheet.setPaperId(answerPoliticsParentDto.getExamPaperId());
        answerSheet.setNumberQuestionsCompleted(correntCount + errorCount);
        answerSheet.setNumberCorrectAnswers(correntCount);
        answerSheet.setNumberIncorrectQuestions(errorCount);
        answerSheet.setTotalNumberQuestions(totalCount);
        answerSheet.setRemainingQuestions(totalCount - correntCount - errorCount);
        answerSheet.setTotalTimeSpent(answerPoliticsParentDto.getTotalTimeSpent()+totalTimeSpent);
        answerSheetService.insert(answerSheet);
        return RestResponse.ok(answerSheet);
    }

    /**
     * 英语模块提交答案
     *
     * @param answerEnglishParentDto
     * @return
     */
    @RequestMapping("/submitAnswerForEnglish")
    @Transactional
    public RestResponse<AnswerSheet> submitAnswerForEnglish(@RequestBody AnswerEnglishParentDto answerEnglishParentDto) {
        List<AnswerEnglishKeyValueDto> requestAnswerChild = answerEnglishParentDto.getUserAnswer();
        if ( CollectionUtils.isEmpty(requestAnswerChild)) {
            logger.info("用户没有选择答案");
            return RestResponse.ok();
        }
        ExamPaper examPaper = examPaperService.getExamPaperById(answerEnglishParentDto.getExamPaperId());
        if (examPaper == null) {
            logger.info("考试试卷不存在");
            return RestResponse.ok();
        }
        //当前用户
        Integer userId = webContext.getCurrentUser().getUserId();

        Collections.sort(requestAnswerChild,(p1,p2) -> p1.getIndex()-p2.getIndex());
        AnswerSheet existSheet = new AnswerSheet();
        existSheet.setUserId(userId);
        existSheet.setPaperId(answerEnglishParentDto.getExamPaperId());
        List<AnswerSheet> answerSheets = answerSheetService.selectList(existSheet);
        Long totalTimeSpent = 0L;
        if (!CollectionUtils.isEmpty(answerSheets)) {
            totalTimeSpent = answerSheets.get(0).getTotalTimeSpent();
            answerSheets.forEach(answerSheet -> {
                answerSheetService.deleteById(answerSheet.getId());
            });
        }
        Integer type = answerEnglishParentDto.getIsTest() == null || !answerEnglishParentDto.getIsTest() ? ExamPaperTypeEnum.EXERCISE.getCode() : ExamPaperTypeEnum.WEEKTEST.getCode();
        List<AnswerContentRecord> answerContentRecordList = answerContentRecordService.selectByExamPaperIdAndUserId(type,answerEnglishParentDto.getExamPaperId(), userId);
        int totalCount = 9;
        int completedCount = answerContentRecordList.size();
        int correntCount = 0;
        int errorCount = 0;
        for (AnswerContentRecord answerContentRecord : answerContentRecordList) {
            QuestionVm questionVm = questionService.selectById(answerContentRecord.getQuestionId());
            if (questionVm == null || questionVm.getCorrect() == null || "".equals(questionVm.getCorrect())) {
                //TODO 没有答案的输入型，先算作正确
                correntCount++;
                continue;
            }
            List<String> userAnswer = answerContentRecord.getContent();
            List<String> correctAnswer = Arrays.asList(questionVm.getCorrect().split(","));
            HashSet<String> a1 = new HashSet<>(userAnswer);
            HashSet<String> a2 = new HashSet<>(correctAnswer);
            if (a1.equals(a2)) {
                correntCount++;
            } else {
                errorCount++;
            }
        }
        //更新用户答题记录
        if(answerEnglishParentDto.getIsTest() == null){
            answerEnglishParentDto.setIsTest(false);
        }
        answerContentRecordService.insertOrUpdateForEnglish(answerEnglishParentDto.getIsTest(),requestAnswerChild, examPaper, userId,answerEnglishParentDto.getQuestionId(),answerEnglishParentDto.getTotalTimeSpent());
        AnswerSheet answerSheet = new AnswerSheet();
        answerSheet.setUserId(userId);
        answerSheet.setNumberQuestionsCompleted(completedCount);
        answerSheet.setNumberCorrectAnswers(correntCount);
        answerSheet.setNumberIncorrectQuestions(errorCount);
        answerSheet.setRemainingQuestions(totalCount - completedCount);
        answerSheet.setTotalNumberQuestions(totalCount);
        answerSheet.setPaperId(answerEnglishParentDto.getExamPaperId());
        answerSheet.setTotalTimeSpent(answerEnglishParentDto.getTotalTimeSpent()+totalTimeSpent);
        answerSheetService.insert(answerSheet);
        return RestResponse.ok();
    }


    public static boolean checkTypeByCast(Object obj) {
        try {
            String[] castArray = (String[]) obj;
            return true;
        } catch (ClassCastException e) {
            if (obj instanceof String) {
                return false;
            } else {
                return false;
            }
        }
    }
    @RequestMapping("/getNumcompleted")
    public RestResponse<List<BigDecimal>> getAnswerSheet(@RequestParam("time") String time){
        Integer userId = webContext.getCurrentUser().getUserId();
        List<BigDecimal> numcompleted = answerSheetService.selectQuestionCompleted(userId,time);
        return RestResponse.ok(numcompleted);
    }

    @GetMapping("/getTotalTime")
    public RestResponse<List<BigDecimal>> getTotalTime(@RequestParam("time") String time) {
        Integer userId = webContext.getCurrentUser().getUserId();
        List<BigDecimal> totalTimeSpent = answerSheetService.selectTotalTime(userId, time);
        return RestResponse.ok(totalTimeSpent) ;
    }

    /**
     * 英语交卷，计算英语成绩
     * @param examPaperId
     * @param timeSpent
     * @return
     */
    @RequestMapping("/calcutateEnglishScore")
    public RestResponse calcutateEnglishScore(@RequestParam(value = "examPaperId")Integer examPaperId,
                                              @RequestParam(value = "timeSpent") Long timeSpent) {
        answerContentRecordService.calcutateEnglishScore(examPaperId,timeSpent);
        return RestResponse.ok();
    }

}
